//
//
#ifndef Point2D_h__
#define Point2D_h__

#include "Gmath.h"
#include "Object2D.h"

namespace Geometric
{
	// Point 2D
	class _GEOMETRIC Point2D
	{
	public:
		// coordinate of a point: (x,y)
		double m_x;
		double m_y;

	public:
		Point2D(double _x, double _y) :m_x(_x), m_y(_y)
		{
		}

		Point2D(const Point2D& _point) :m_x(_point.m_x), m_y(_point.m_y)
		{
		}

		Point2D() :m_x(0), m_y(0)
		{
		}

		~Point2D()
		{
		}

	public:
		inline Point2D& operator = (const Point2D& _point)
		{
			this->m_x = _point.m_x;
			this->m_y = _point.m_y;
			return (*this);
		}

		friend inline bool operator == (const Point2D& _point1, const Point2D& _point2)
		{
			return(Gmath::isEqual(_point1.m_x, _point2.m_x) 
				&& Gmath::isEqual(_point1.m_y, _point2.m_y));
		}

		friend inline bool operator != (const Point2D& _point1, const Point2D& _point2)
		{
			return !(_point1 == _point2);
		}

	public:
		// if the object is valid
		inline virtual bool isValid()
		{
			return true;
		}

		// set the value of the point
		inline void set(double _x, double _y)
		{
			this->m_x = _x;
			this->m_y = _y;
		}

		inline void set(const Point2D& _point)
		{
			set(_point.m_x, _point.m_y);
		}

		// set the point as origin
		inline void setZero()
		{
			m_x = m_y = 0.0;
		}
		
		// get the distance of two points
		inline double getDistance(double _x, double _y)
		{
			double square = Gmath::toPow(m_x - _x, 2) + Gmath::toPow(m_y - _y, 2);
			return Gmath::toSqrt(square);
		}

		inline double getDistance(const Point2D& _point)
		{
			return getDistance(_point.m_x, _point.m_y);
		}

		// if the two points are coinciding
		inline bool isOverlap(double _x, double _y)
		{
			return (Gmath::isEqual(m_x, _x) && Gmath::isEqual(m_y, _y));
		}

		inline bool isOverlap(const Point2D& _point)
		{
			return isOverlap(_point.m_x, _point.m_y);
		}

		inline virtual void translate(double _x, double _y)
		{
			m_x += _x;
			m_y += _y;
		}

		inline void rotate(double _angle)
		{
			double cos_angle = ::cos(_angle);
			double sin_angle = ::sin(_angle);
			double tmp_x = m_x;
			double tmp_y = m_y;
			m_x = cos_angle*tmp_x - sin_angle*tmp_y;
			m_y = sin_angle*tmp_x + cos_angle*tmp_y;
		}

		inline virtual void scale(double _x, double _y)
		{
			m_x *= _x;
			m_y *= _y;
		}

	};


}

#endif
